#include <HumanManager.h>

// Constructores y destructores ----------------------------------------

template<> HumanManager* Ogre::Singleton<HumanManager>::ms_Singleton = 0;

HumanManager::HumanManager(btDiscreteDynamicsWorld* pWorld,
                           Ogre::SceneManager* pSceneManager,
                           OpenSteer::Vec3 position) :
  _pWorld(pWorld), _pSceneManager(pSceneManager) {

  Ogre::Entity* pHumanEntity =
    _pSceneManager->createEntity(HUMANMESH);

  BtOgre::StaticMeshToShapeConverter converter(pHumanEntity);

  _pHumanCollisionShape = converter.createCylinder();

  _pSceneManager->destroyEntity(pHumanEntity);

  _pHuman = new Human(_pWorld, _pHumanCollisionShape, _pSceneManager,
                      position);

  _pShootRaySceneQuery = _pSceneManager->createRayQuery(Ogre::Ray());
}

HumanManager::~HumanManager() {

  delete _pHuman;
  delete _pHumanCollisionShape;

  _pSceneManager->destroyQuery(_pShootRaySceneQuery);
}

// Ogre::Singleton -----------------------------------------------------

HumanManager&
HumanManager::getSingleton() {

  assert(ms_Singleton);
  return *ms_Singleton;
}

HumanManager*
HumanManager::getSingletonPtr() { return ms_Singleton; }

// Update --------------------------------------------------------------

void
HumanManager::update(const float currentTime,
                     const float elapsedTime) {

  if (_pHuman != NULL)
    _pHuman->update(currentTime, elapsedTime);
}

// Métodos propios -----------------------------------------------------

void
HumanManager::translate(btVector3 translation) {

  if (_pHuman != NULL)
    _pHuman->translate(translation);
}

void
HumanManager::lookAt(Ogre::Vector3 targetPoint) {

  if (_pHuman != NULL)
    _pHuman->lookAt(targetPoint);
}

bool HumanManager::shoot()
{
  bool r = false;

  Ogre::Vector3 origin(_pHuman->position().x,
                       _pHuman->position().y,
                       _pHuman->position().z);

  Ogre::Vector3 direction(_pHuman->forward().x,
                          _pHuman->forward().y,
                          _pHuman->forward().z);

  Ogre::Ray shootRay(origin, direction);
  _pShootRaySceneQuery->setRay(shootRay);
  _pShootRaySceneQuery->setSortByDistance(true);
  _pShootRaySceneQuery->setQueryMask(QUERY_MASK_ZOMBIE);

  Ogre::RaySceneQueryResult& result = _pShootRaySceneQuery->execute();
  Ogre::RaySceneQueryResult::iterator it;

  it = result.begin();

  if (it != result.end()) {

    Zombie* pZombie = Ogre::any_cast<Zombie*>(it->movable->getUserAny());
    r = pZombie->doDamage(1);
  }

  return r;
}
